package webprinter;

import java.util.Arrays;
import java.util.List;
import java.util.Map;

import utils.TimeResponseMonitor;
import eduni.simjava.Sim_port;
import eduni.simjava.Sim_stat;
import eduni.simjava.Sim_system;
import entites.LAN;
import entites.Printer;
import entites.Spooler;
import entites.Source;

public class Main {
	
	public static void main(String[] args) {
		double tmpArray[] = new double[args.length];
		for(int i = 0; i < args.length; i++) {
			tmpArray[i] = Double.parseDouble(args[i]);
		}
		double params[] = {2, 5, 0.33, 0.99, 1.50, 2.38};//, 1.1, 1.23, 0.5, 4, 0.1, 20, 69 };
		params = tmpArray;
		Sim_system.initialise();

		// Cria os recursos invariáveis
		Sim_system.add(new Source("source", params[0]));
		Sim_system.add(new Source("priority_source", params[1]));
		
		Spooler spooler = new Spooler("spooler", params[2]);
		Sim_system.add(spooler);
		
		TimeResponseMonitor monitor = new TimeResponseMonitor("monitor");
		Sim_system.add(monitor);
		
		LAN lan = new LAN("lan", params[3]);
		Sim_system.add(lan);

		// Conecta a internet ao spooler
		Sim_system.link_ports("source", "toSpooler", "spooler", "fromSource");
		Sim_system.link_ports("priority_source", "toSpooler", "spooler", "fromPrioritySource");
		
		// Conecta o spooler ao monitor que ira calcular o tempo de resposta
		Sim_system.link_ports("spooler", "toMonitor", "monitor", "fromSpooler");
		
		// Conecta o spooler a LAN
		Sim_system.link_ports("spooler", "toLan", "lan", "fromSpooler");

		// Conecta a lan ao spooler
		Sim_system.link_ports("lan", "toSpooler", "spooler", "fromLan");

		/**
		 * A partir daqui cria os recursos variáveis (impressoras)
		 */

		// Cria todas as "N" impressoras e conecta a LAN com as impressoras.
		// OBS: Também instala as impressora (spooler precisa conhecer todas)
		double[] printMeans = Arrays.copyOfRange(params, 4, params.length);
		Integer count = 0;
		for (double parametro : printMeans) {
			String name = "printer" + count.toString();

			Sim_system.add(new Printer(name, parametro));

			String toPrinter = "toPrinter" + count.toString();
			Sim_port portToPrinter = new Sim_port(toPrinter);
			lan.add_port(portToPrinter);

			Sim_system.link_ports("lan", toPrinter, name, "fromLan");
			Sim_system.link_ports(name, "toLan", "lan", "fromPrinter");

			spooler.install_printer(name, toPrinter);
			count++;
		}

		// Condição de parada
		Sim_system.set_termination_condition(Sim_system.INTERVAL_ACCURACY,
				Sim_system.IND_REPLICATIONS, 0.90, 0.1, "spooler",
				Sim_stat.UTILISATION);
				
		Sim_system.run();
		
		System.out.println("\n----------------------------");
		System.out.println("Quantidade de impressões realizados por impressora em cada rodada de simulação: ");
		Map<String, List<Integer>> printers = monitor.getPrintersHistory();
		for (String printer : printers.keySet()) {
			System.out.println(printer + ": " + printers.get(printer).toString());
		}
		
		// Exibi resultado da medição do tempo de resposta e quantidade de 
		// impressões por impressora.
		System.out.println("\n----------------------------");
		Map<String, Double> data = monitor.getData();
		for (String param : data.keySet()) {
			System.out.println(param + ": " + data.get(param).toString());
		}
	}

}
